<?php
namespace Home\Service;
use Think\Controller;
// +----------------------------------------------------------------------
// | Date:2017年2月13日
// +----------------------------------------------------------------------
// | Author: EK_熊<1439527494@qq.com>
// +----------------------------------------------------------------------
// | Description: 此文件作用于计算【打卡时间点】的相关信息
// +----------------------------------------------------------------------
class ClockTimeService extends Controller{
    
    protected $clockTime = '';
    public $day_cur = '';
    public $config = '';
    protected $duty_on='';
    protected $duty_off='';
    
    protected $work_day_begin='';
    protected $work_day_stop='';
    
    protected $rest_midday = '';
    protected $rest_dinner = '';
    protected $effect_blank = '';
    
    protected $dutyOnTime = '';//上班打卡点，即当天第一次打卡的时间点
    protected $leaveMins = 0;//请假时间，分钟数
    protected $evectionMins = 0;//外出时间，分钟数，要计算到加班时间的
    protected $fullTime = 8*60;//标准的一天全勤分钟数
    
    protected $apply_time_min = '';//申请的开始时间中最小值
    protected $apply_time_max = '';//申请的结束时间中最大值
    protected $apply_overlap = 0;//打卡和申请数据的重叠区间的总分钟数
    protected $apply_count = [];//申请情况，类型以及分钟数
    
    protected $clockInfo=[];//打卡产生的打卡数据
    
    protected $configExt = [
        'isclock'=>true,
    ];
    
    /**
     * 构造函数
     * @param string $clockTime     单独打卡时间，
     * @param string $dutyOnTime    设置上班时间，如果不填，则clockTime默认为上班时间执行操作
     * @param string $config        配置拓展：isclock ：是否识别为正常的人工打卡，计算有效时间等相关数据
     * date:2017年2月22日
     * author: EK_熊
     */
    public function __construct($dutyOnTime='',$clockTime='',$config=[]){
        parent::__construct();
        $this->config =[
            'actual_work_day'=>C('ACTUAL_WORK_DAY'),
            'rest_midday'=>C('REST_MIDDAY'),
            'rest_dinner'=>C('REST_DINNER'),
            'duty_on'=>C('DUTY_ON'),
            'duty_off'=>C('DUTY_OFF'),
            'effect_blank'=>C('ETTECT_BALNK'),
        ];

        $this->dutyOnTime = $this->clockTime = $clockTime && is_string($clockTime) ? strtotime($clockTime) : $clockTime;
        if ($dutyOnTime) {
            $this->dutyOnTime = is_string($dutyOnTime) ? strtotime($dutyOnTime) : $dutyOnTime;
        }
        $this->_set_config($this->dutyOnTime,$this->clockTime,$config);
    }
    
    //设置配置信息
    private function _set_config($dutyOnTime='',$clockTime='',$config=[]){
        if ($config) $this->configExt = $config;
        
        $this->day_cur = $this->_get_cuy_day($dutyOnTime,$clockTime);
        
        $this->duty_on = $this->get_config_timestamp($this->config['duty_on']);
        $this->duty_off = $this->get_config_timestamp($this->config['duty_off']);
        
        //早上正常上班：8:30~11:59
        $this->work_day_begin = $this->get_config_timestamp($this->config['actual_work_day'][0]);
        $this->work_day_stop = $this->get_config_timestamp($this->config['actual_work_day'][1]);
        //午休时间：12:00~12:59
        $this->rest_midday[0] = $this->get_config_timestamp($this->config['rest_midday'][0]);
        $this->rest_midday[1] = $this->get_config_timestamp($this->config['rest_midday'][1]);
        //晚餐时间：18:00~20:00
        $this->rest_dinner[0] = $this->get_config_timestamp($this->config['rest_dinner'][0]);
        $this->rest_dinner[1] = $this->get_config_timestamp($this->config['rest_dinner'][1]);
        
        $this->effect_blank[0] = $this->get_config_timestamp($this->config['effect_blank'][0]);
        $this->effect_blank[1] = $this->get_config_timestamp($this->config['effect_blank'][1]);
        $this->config = $this->config + $this->configExt;

    }
    
    private function _get_cuy_day($dutyOnTime='',$clockTime=''){
        $dayStart = $this->work_day_begin;
        if ($dutyOnTime){
            $timestamp = $dutyOnTime;
        }elseif(!$dutyOnTime && $clockTime){
            $timestamp = $clockTime;
        }else{
            return date('Y-m-d');
        }
        if ($timestamp >= $dayStart) {
            return date('Y-m-d',$timestamp);
        }else{
            return date('Y-m-d',$timestamp-86400);
        }
    }
    
    /**
     * 根据打卡时间时间点确定打卡日期,拼接配置时间点,获取返回当前配置信息的完整的日期时间戳
     * @param unknown $time     传入时间字符串：'06:00:00'
     * @param unknown $dayNum   当天的不用传参数，+1后一天；-1前一天
     * @param unknown $setTime   手动传入打卡时间
     * date:2017年2月13日
     * author: EK_熊
     */
    public function get_config_timestamp($timeString,$dayNum='',$setTime=''){
        $clockTime = $this->dutyOnTime ? $this->dutyOnTime : $this->clockTime;
//         $curDay = date("Y-m-d",$clockTime);
        $curDay = $this->day_cur;
        if (!empty($setTime)){
            $clockTime = is_string($setTime) ? strtotime($setTime) : $setTime;
        }
        if (!$dayNum){
            $timeStamp = strtotime("$curDay $timeString");//当天的时间
        }else{
            $day_cur = date("Y-m-d",strtotime("$dayNum day",$clockTime));
            $timeStamp = strtotime("$day_cur $timeString");
        }
        return $timeStamp;
    }
    
    
    
    
    /**
     * 传入打卡时间，计算实际出勤时间，排除中间午休时间
     * 实际 = 实际+外出
     * @param unknown $switch  是否开启工作日检查
     * date:2017年2月13日
     * author: EK_熊
     */
    public function work_actual_time(){
        
        $time = $this->clockInfo['clock_actual']+$this->evectionMins['actual'];
        return $time;
    }
    
    /**
     * 实际工时的计算规则：返回分钟数
     * 排除 12:00~13:00
     */
    private function _rule_actual($startTime,$endTime){
        /* 当天初次打卡时间的特殊情况处理 */
        if($startTime >= $this->rest_midday[0] && $startTime <= $this->rest_midday[1]){
            $startTime = $this->rest_midday[1];
        }
        
        if ($endTime>= $this->rest_midday[0] && $endTime <= $this->rest_midday[1]) {
            $endTime = $this->rest_midday[0];
        }
        if ($startTime < $this->rest_midday[0] && $endTime >= $this->rest_midday[1]) {
            $worktime = $endTime - $startTime - 60*60;
        }else{
            $worktime = $endTime - $startTime;
        }  
        
        return $this->get_minute($worktime);
    }
    
    
    /**
     * 传入打卡时间，计算有效出勤时间
     * 有效 = 有效+外出
     * date:2017年2月13日
     * author: EK_熊
     */
    public function work_effect_time(){
//         if (!is_work_day($this->day_cur)){
//             return 0;
//         }
//         if ($this->dutyOnTime && $this->dutyOnTime == $this->clockTime) {
//             if (!$this->evectionMins['effect']){
//                 return 1;
//             }else{
//                 return $this->evectionMins['effect'];
//                 }
//         }
//         $startTime = $this->dutyOnTime;
//         $endTime = $this->clockTime;
        $time = $this->clockInfo['clock_effect']+$this->evectionMins['effect'];
        return $time;
        
    }
    
    /**
     * 有效工时计算规则，返回分钟数
     * 排除 8：30~9:00,12:00~13:00,18:00~20:00
     */
    private function _rule_effect($startTime,$endTime){
        /* 当天初次打卡时间的特殊情况处理，8:30~9:00空白区域 */
        if ($startTime >= $this->effect_blank[0] && $startTime <= $this->effect_blank[1]){
            $startTime = $this->duty_on;   //如果8：30前打卡，打卡时间是8:30
        }
        
        //上班时间，是午餐范围内
        if($startTime >= $this->rest_midday[0] && $startTime <= $this->rest_midday[1]){
            $startTime = $this->rest_midday[1];
        }
        
        if ($endTime>= $this->rest_midday[0] && $endTime <= $this->rest_midday[1]) {
            $endTime = $this->rest_midday[0];
        }
        if ($startTime >= $this->rest_dinner[0] && $startTime <= $this->rest_dinner[1]) {
            $startTime = $this->rest_dinner[1];
        }
        
        //下班时间如果是18:00~20:00 ,即结束时间改为18:00
        if ($endTime >= $this->rest_dinner[0] && $endTime <= $this->rest_dinner[1]){
            $endTime = $this->rest_dinner[0];
        }
        
        if($endTime > $this->rest_dinner[1] && $startTime <= $this->rest_midday[0]){
            $worktime = $endTime-$startTime-60*60*3;//扣除3个小时，午休1个小时，晚餐2个小时
        }elseif (($startTime < $this->rest_midday[0] && $endTime > $this->rest_midday[1] && $endTime < $this->rest_dinner[1])) {
            $worktime = $endTime-$startTime-60*60;//下午正常上班时间
        }elseif ($startTime >= $this->rest_midday[1] && $startTime < $this->rest_dinner[0] && $endTime >= $this->rest_dinner[1]){
            $worktime = $endTime-$startTime-60*60*2;//下午正常上班时间
        }else{
            $worktime = $endTime-$startTime;//在有限出勤时间范围内上班打卡
        }
        if ($startTime > strtotime("{$this->day_cur} 06:00:00") && $startTime < $this->effect_blank[0] && $startTime < strtotime("{$this->day_cur} 23:59:59")){
            $worktime = $worktime - 30*60;
        }
        return $this->get_minute($worktime);
    }
    
    
    /**
     * 传入打卡时间，计算9点到18点的有效出勤分钟数
     * 
     * date:2017年3月8日
     * author: EK_熊
     */
    public function work_effect_time_918(){
//         if (!is_work_day($this->day_cur)) return 0;
//         if ($this->dutyOnTime && $this->dutyOnTime == $this->clockTime) {
//             if (!$this->evectionMins['effect_918']){
//                 return 1;
//             }else{
//                 return $this->evectionMins['effect_918'];
//                 }
//         }
//         $effect_918 = $this->_rule_effect_918($this->dutyOnTime, $this->clockTime);
//         $worktime = $effect_918+$this->evectionMins['effect_918'];

        $worktime = $this->clockInfo['clock_effect_918'] + $this->evectionMins['effect_918'];
        return $worktime > 480 ? 480:$worktime;
    }
    
    private function _rule_effect_918($start,$end){
       
        $work_s = $this->duty_on;
        $work_e = $this->duty_off;
        if ($start >= $this->rest_midday[0] && $start <=$this->rest_midday[1]){
            $start = $this->rest_midday[1];
        }elseif($start < $work_s) {
            $start = $work_s;
        }
        if ($end > $work_e) $end = $work_e;
        if ($end < $this->rest_midday[1] && $end > $this->rest_midday[0]) $end = $this->rest_midday[0];
        
        if ($start < $this->rest_midday[0] && $end >$this->rest_midday[1]) {
            $worktime = $end - $start - 3600;
        }else{
            $worktime = $end - $start;
        }   
        return $this->get_minute($worktime);
    }
    
    /**
     * 计算当天超时的工作分钟数，如果是周六日打卡处理为加班
     * 1.加班的时长显示条件：1有打卡；2有审核通过的申请数据进来
     * @param unknown $dutyOnTime
     * date:2017年2月14日
     * author: EK_熊
     */
    public function work_over_time(){
        
        /*如果是非工作日：
         *  加班时长的计算：加班申请时长>打卡时长  取 打卡时长；
         *             加班申请时长<打卡时长 取 加班申请时长
         * 非工作日只有三种申请情况：出差，外出，加班申请
         */
        if (!is_work_day($this->day_cur)){ 
//             $overtime = $this->_rule_weekend();
            $overtime = $this->work_actual_time(false);
            return $overtime>480 ? 480 : $overtime;
        }
        $overtime = $this->work_effect_time() - 480;    //加班 = 有效-480      
        
        return $overtime >0 ? $overtime : 0;
    }
    
    
    
    public function attendance_weekend($timeList){
        $attInfo = $this->_clock_info();
        $isClock = true;
        if ($this->dutyOnTime && $this->clockTime) {
            $attInfo['duty_off'] = date("Y-m-d H:i:s",$this->clockTime);
        }else{
            $isClock = false;
        }
        
        if (empty($timeList)) return $attInfo;
        $leave = [];
        $ot_total_min = 0;
        foreach ($timeList as $k => $v) {
            if ($v['label'] == 'ot_weekend'){
                $ot_start = strtotime($v['interval'][0]);
                $ot_end = strtotime($v['interval'][1]);
                $ot_min = $this->_rule_actual($ot_start, $ot_end);//加班申请的时间段
                $ot_intval[] = [$ot_start,$ot_end];//加班申请的时间段,把ot的申请存起来
                $ot_total_min += $ot_min;//加班申请总长度
            }
            
            if ($v['label'] == 'leave_evection' || $v['label'] == 'leave_long_distance'){
                $leave[] = $v;
            }
        }
        
        if ($ot_total_min && $isClock){
            $attInfo['overtime'] = $ot_total_min;
            //有加班申请数据,对比打卡时长和加班申请时长
            $actual = $this->_rule_actual($this->dutyOnTime, $this->clockTime);
            //加班申请集合的子元素和打卡时间做长度比较，算出加班时间

            if ($actual > 0 ) {
                if ($actual <= $ot_total_min){
                    //打卡比较小，取打卡时间
                    $attInfo['overtime'] = $actual;
                    $ot_intval = [];
                    $ot_intval[] = [$this->dutyOnTime,$this->clockTime];
                }
            }
            foreach ($ot_intval as $v) {
                $attInfo['work_actual'] += $this->_rule_actual($v[0], $v[1]);
                $attInfo['work_effect'] += $this->_rule_effect($v[0], $v[1]);
            }
        }
        
        //检查是否有外出申请数据
        if ($leave){
            $total_leave_actual = 0;
            $total_leave_effect = 0;
            $total_overlap = 0;
            foreach ($leave as $k=>$v){
                $le_start = strtotime($v['interval'][0]);
                $le_end = strtotime($v['interval'][1]);
                
                if (!$isClock) $this->_set_config($le_start,$le_end);
                if ($ot_intval){
                    //做区间判断,累计多条申请和加班区间的重叠数值
                    foreach ($ot_intval as $v_ot_intval){
                        $overlap = $this->_overlap($v_ot_intval, [$le_start,$le_end]);
                        $total_overlap += $overlap;
                    }
                }
                //累计外出分钟值
                $leave_actual = $this->_rule_actual($le_start, $le_end);
                
                $total_leave_actual += $leave_actual;
    
                $leave_effect = $this->_rule_effect($le_start, $le_end);
                $total_leave_effect += $leave_effect;
    
                $attInfo[$v['label']] += $leave_actual - $total_overlap;
            }
            //如何有重叠数据
            $ot_actual = $attInfo['overtime'] + $total_leave_actual - $total_overlap;
           
            $attInfo['work_actual'] = $ot_actual;
            $attInfo['work_effect'] = $attInfo['work_effect'] + $total_leave_effect - $total_overlap;
            $attInfo['overtime'] = $ot_actual > 480 ? 480 : $ot_actual;
        }        
        
        return $attInfo;
            
        
    }
    
    
    /**
     * 缺勤分钟数
     * 缺勤时间 = 全勤时间-有效工作时间-外出时间
     * 缺勤的显示区别：工作日显示，非工作日显示0，如果是请假，要调用set_leave_min()方法
     * date:2017年2月14日
     * author: EK_熊
     */
    public function stu_absence(){
        if (!is_work_day($this->day_cur)){
            return 0;
        }
        //缺勤时间 = 480-外出分钟数-实际出勤分钟数
        $absence = $this->fullTime - $this->work_actual_time();
        return $absence > 0 ? $absence : 0;
    }
    
    /**
     * 设置离开时间，可能是请假（属于非工作时间），可能是外出（属于工作时间）
     * @param unknown $leavelmins
     * date:2017年3月10日
     * author: EK_熊
     */
    public function set_leave_min($leavelmins){
        $this->leaveMins = $leavelmins;
        return $this;
    }
    
    /**
     * 设置外出，时间，外出时间是要计算到加班时间里面的
     * @param unknown $leavelmins
     * date:2017年3月17日
     * author: EK_熊
     */
    public function set_evection_min($startTime,$endTime){
        $startTime = is_string($startTime) ? strtotime($startTime) : $startTime;
        $endTime = is_string($endTime) ? strtotime($endTime) : $endTime;
        $this->evectionMins = [
            'effect'=>$this->_rule_effect($startTime, $endTime),
            'actual'=>$this->_rule_actual($startTime, $endTime),
            'effect_918'=>$this->_rule_effect_918($startTime, $endTime),
        ];
        return $this;
    }
    
    /**
     * 传入申请的起止时间(数组形式，可以传多个申请)，对比打卡时间上下班卡，计算重叠区间的时长
     * 备注：如果每个申请的区域存在重叠区间时，会出现问题，不过因为前端提交时以及做了重叠判断，暂时无需考虑
     * @param unknown $timeList
     * date:2018年3月26日
     * author: EK_熊
     */
    public function set_apply_time($timeList){
        if (empty($timeList)) return $this;
        $this->apply_list = $timeList;
        foreach ($timeList as $k => $v) {
            $aply_s = strtotime($v['interval'][0]);
            $aply_e = strtotime($v['interval'][1]);
            
            
            if ($aply_s < $aply_e){
                $aply_overlap = 0;
                $apply_days = ceil(($aply_e-$aply_s)/86400);//申请天数
                if ($apply_days > 1){
                    //如果是跨天的申请时间段，要和标准的上下班时间点做区间比较
                    $duty = $this->_overlap([$aply_s,$aply_e],[$this->duty_on,$this->duty_off],2);
                    $aply_s = $duty[0];
                    $aply_e = $duty[1];
                }

                if ($this->dutyOnTime && $this->clockTime) {
                    $aply_overlap = $this->_overlap([$this->dutyOnTime,$this->clockTime],[$aply_s,$aply_e]);
                    $this->apply_overlap += $aply_overlap;
                }
                if (!$this->dutyOnTime && !$this->clockTime) {
                    $this->_set_config($aply_s,$aply_e);
                }
                
                $aply_actual = $this->_rule_actual($aply_s, $aply_e);//计算申请的实际申请时间
                $aply_effect = $this->_rule_effect($aply_s, $aply_e);//计算申请的有效申请时间
                $aply_effect_918 = $this->_rule_effect_918($aply_s, $aply_e);//计算918有效时间
                
                $time_s[] = $aply_s;
                $time_e[] = $aply_e;
                if (isset($this->apply_count[$v['label']])){
                    $this->apply_count[$v['label']] += $aply_actual - $aply_overlap;
                }else{
                    $this->apply_count[$v['label']] = $aply_actual - $aply_overlap;
                }
                $aply_t_effect +=$aply_effect;
                $aply_t_actual +=$aply_actual;
                $aply_t_effect_918 +=$aply_effect_918;
            }
        }
//         dump($aply_t_effect);
//         dump($aply_t_actual);
//         dump(date('Y-m-d H:i:s',$aply_s));
//         dump(date('Y-m-d H:i:s',$aply_e));
        $aply_t_effect_918 = $aply_t_effect_918 - $this->apply_overlap;

        if ($aply_t_effect_918 < 0 ) $aply_t_effect_918 = 0;
        if ($aply_t_effect_918 >480) $aply_t_effect_918 = 480;

        $this->apply_time_min = min($time_s);//取出申请时间的最小值
        $this->apply_time_max = max($time_e);//取出申请时间的最大值
        if ($aply_actual > $this->apply_overlap || !$aply_actual) {
            $this->evectionMins = [
                'effect'=>$aply_t_effect - $this->apply_overlap,
                'actual'=>$aply_t_actual - $this->apply_overlap,
                'effect_918'=>$aply_t_effect_918,
            ];
        }
       return $this;
    }

    
    /**
     * 继续重叠的区间值
     * @param unknown $a
     * @param unknown $b
     * @param unknown $model   模式1 返回重叠数，模式2，返回起止点
     * date:2018年3月27日
     * author: EK_熊
     */
    public function _overlap($a=[],$b=[],$model = 1){
//         dump('a0:'.date('Y-m-d H:i:s',$a[0]));
//         dump('a1:'.date('Y-m-d H:i:s',$a[1]));
        
//         dump('b0:'.date('Y-m-d H:i:s',$b[0]));
//         dump('b1:'.date('Y-m-d H:i:s',$b[1]));
        $overlap = 0;
        if (($b[0] >= $a[0]) && ($b[0] < $a[1])){
            $overlap_s = $b[0];
            $overlap_e = $b[1];
            if ($b[1] >= $a[1] ){
                $overlap_e = $a[1];
            }
        }
        
        if (($b[1] >= $a[0]) && ($b[0] < $a[0])){
            $overlap_s = $a[0];
            $overlap_e = $a[1];
            if ($b[0] <= $a[0] ){
                $overlap_e = $b[1];
            }
        }
        if ($model == 2) return [$overlap_s,$overlap_e];
        if ($overlap_s && $overlap_e){
            $overlap = $this->_exclude_rest($overlap_s,$overlap_e,'min');
        }
        
        return $overlap;
    }
    
     /**
      * 设置申请的时长
      * 时长 = 时长 - 申请和打卡的重叠区间
      * @param unknown $min
      * date:2018年3月27日
      * author: EK_熊
      */   
     public function set_evection_min_2($min){
        $startTime = is_string($startTime) ? strtotime($startTime) : $startTime;
        $endTime = is_string($endTime) ? strtotime($endTime) : $endTime;
        $this->evectionMins = [
            'effect'=>$min - $this->apply_overlap,
            'actual'=>$min - $this->apply_overlap,
            'effect_918'=>$min - $this->apply_overlap,
        ];
        return $this;
    } 
    
    
    /**
     * 迟到分钟数
     * 
     * date:2017年2月14日
     * author: EK_熊 
     */
    public function stu_late(){
        if (!is_work_day($this->day_cur) || !$this->config['isclock']) return 0;
        if (empty($this->dutyOnTime) && !$this->apply_time_min) return 0;

        $clockTime = $this->dutyOnTime;
        
        if (!$clockTime || ($this->apply_time_min && ($this->apply_time_min < $clockTime))){
            $clockTime = $this->apply_time_min;
        }

        if ($clockTime >= $this->rest_midday[0] && $clockTime <$this->rest_midday[0]) {
            $late = $this->work_am[1] - $this->duty_on;
        }elseif($clockTime >= $this->rest_midday[1]){
            $late = $clockTime - $this->duty_on - 60*60;
        }else{
            $late = $clockTime - $this->duty_on;
        }
        
        return $this->get_minute($late);
    }
    
    /**
     * 早退
     * 早于18:00 属于早退
     * date:2017年2月14日
     * author: EK_熊
     */
    public function stu_leave_early(){
        $early = 0;
        if (!is_work_day($this->day_cur) || !$this->config['isclock']) return $early;
        if (!$this->clockTime && !$this->apply_time_max) return $early;
        $clockTime = $this->clockTime ? $this->clockTime : $this->dutyOnTime;
        
        if ($this->apply_time_max && ($this->apply_time_max > $clockTime)){
            $clockTime = $this->apply_time_max;
        }
        
        if ($clockTime < $this->duty_off) {
            if ($clockTime <= $this->rest_midday[0]) {
                $early = $this->duty_off - $clockTime - 60*60;
            }else {
                $early = $this->duty_off - $clockTime;
            }
        }
        return $this->get_minute($early);
    }
    
    /**
     * 
     * 
     * date:2017年2月22日
     * author: EK_熊
     */
    
    
    /**
     * 获取当天的考勤情况
     * @param unknown $timeList 数组，申请数据的时间集合
     * 格式示例： [
            ['interval'=>['2018-03-30 17:00:00','2018-03-31 08:00:00'],'label'=>'leave_evection'],
            ['interval'=>['2018-03-28 17:00:00','2018-03-28 18:00:00'],'label'=>'leave_evection'],
        ] 
     * date:2018年4月2日
     * author: EK_熊
     */
    public function attendance_info($timeList){
        $this->_clock_info();
        
        if (!is_work_day($this->dutyOnTime)) {
            //如果是公休日
            return $this->attendance_weekend($timeList);
        }
        $this->set_apply_time($timeList);
        
        $data = [
            'work_actual'=>$this->work_actual_time(),
            'work_effect'=>$this->work_effect_time(),
            'overtime'=>$this->work_over_time(),
            'stu_absent'=>$this->stu_absence(),
            'stu_late'=>$this->stu_late(),
            'stu_leave_early'=>$this->stu_leave_early(),
            'work_effect_918'=>$this->work_effect_time_918(),
        ];
        
        $data = array_merge($this->clockInfo , $data);

        if ($this->apply_count) $data = $data + $this->apply_count;
        return $data;
    }
    
   private function _clock_info(){
       $clock_actual = $this->_rule_actual($this->dutyOnTime, $this->clockTime);
       $clock_effect = $this->_rule_effect($this->dutyOnTime, $this->clockTime);
       $clock_effect_918 = $this->_rule_effect_918($this->dutyOnTime, $this->clockTime);
       $this->clockInfo = [
           'clock_actual'=>$clock_actual,
           'clock_effect'=>$clock_effect,
           'clock_effect_918'=>$clock_effect_918,
           'overtime'=> 0,
       ];
       
//        if ($this->dutyOnTime && $this->dutyOnTime == $this->clockTime){
//            $this->clockInfo['clock_actual'] = $clock_actual == 0 ? 1 : $clock_actual;
//            $this->clockInfo['clock_effect'] = $clock_effect == 0 ? 1 : $clock_effect;
//            $this->clockInfo['clock_effect_918'] = $clock_effect_918;
//            $this->clockInfo['overtime'] = 0;
//        }
   }
    
    /**
     * 获取分钟数
     * 四舍五入取整数
     * date:2017年2月15日
     * author: EK_熊
     */
    public function get_minute($num){
        $ret = round($num/60);
        $ret = $ret > 0 ? $ret : 0;
        return $ret;
    }
    
    /**
     * 获取当前打卡时间记录的归属日期
     * 
     * date:2017年2月15日
     * author: EK_熊
     */
     public function get_date(){
        return $this->day_cur;
        
    } 
    
    public function debug() {
        dump(date('Y-m-d H:i:s',$this->dutyOnTime));
        dump(date('Y-m-d H:i:s',$this->clockTime));
    }
    
    
    /**
     * 传入间隔起止时间，区别于上下班时间，适用于计算请假时间范围，因为同时会出现，上下班的时间点已经请假的起止时间点，需要对两个不同的时间段获取不同的计算数据
     * @param unknown $start
     * @param unknown $end
     * date:2017年5月5日
     * author: EK_熊
     */
    public function get_intrval_start_end($start,$end,$return ='min'){
        $this->dutyOnTime = strtotime($start);
        $this->clockTime = strtotime($end);
        return $this->get_intrval_work_time($return);
        
    }
    
    
    /**
     * 根据开始和结束时间，计算时间间隔的有效工时时间数据，返回：总分钟数，总天数，总小时数
     * @param unknown $return   all输出全部，min总分钟，hour总小时数，day总天数
     * date:2017年2月22日
     * author: EK_熊
     */
    public function get_intrval_work_time($return='all'){
        
        $start = $this->dutyOnTime;
        $end = $this->clockTime;
        return $this->_exclude_rest($start, $end,$return);
        
    }
    
    
    /**
     * 排除休息时间
     * @param unknown $start
     * @param unknown $end
     * @param unknown $return   可选 all/min/hour/day
     * date:2018年3月27日
     * author: EK_熊
     */
    private function _exclude_rest($start,$end,$return){
        $start_day = date("Y-m-d",$start);
        $end_day =  date("Y-m-d",$end);
        
        $start_reset[0] = strtotime("$start_day {$this->config['rest_midday'][0]}");
        $start_reset[1] = strtotime("$start_day {$this->config['rest_midday'][1]}");
        $start_dutyoff = strtotime("$start_day {$this->config['duty_off']}");
        
        $end_reset[0] = strtotime("$end_day {$this->config['rest_midday'][0]}");
        $end_reset[1] = strtotime("$end_day {$this->config['rest_midday'][1]}");
        $end_dutyon = strtotime("$end_day {$this->config['duty_on']}");
        
        $intrval_day = ceil(($end - $start)/86400);//计算天数
        //解决，如果是在午休时间的问题
        if ($start > $start_reset[0] && $start <= $start_reset[1]) {
            $start = $start_reset[1];
        }
        
        if ($end > $end_reset[0] && $end <= $end_reset[1]) {
            $end = $end_reset[0];
        }
        
        if ($intrval_day >= 2) {
            $middle_total_day = $intrval_day - 2;
            $middle_total_day = $middle_total_day > 0 ? $middle_total_day : 0;//天数
            $middle_total = 28800*$middle_total_day;//一天8个工时的总秒数28800 * 间隔的天数
        
            $intrval_start = $start_dutyoff - $start;
            if ($start < $start_reset[0]) {
                $intrval_start = $intrval_start-3600;
            }
            $intrval_end = $end - $end_dutyon;
            if ($end >= $end_reset[1]) {
                $intrval_end = $intrval_end-3600;
            }
            $intrval_total = $intrval_start + $middle_total + $intrval_end;
        }elseif($intrval_day <= 1){ //天数是1
        
            if ($start < $start_reset[0] && $end >= $end_reset[1]){
                $intrval_total = $end - $start - 3600;
            }else{
                $intrval_total = $end - $start;
            }
        
        }
        $data['total_day'] = $intrval_day;
        $data['total_min'] = round(($intrval_total)/60);
        $data['total_hour'] = round($data['total_min']/60,2);
        switch ($return) {
            case 'day': return $data['total_day'];break;
            case 'min': return $data['total_min'];break;
            case 'hour': return $data['total_hour'];break;
            case 'all': return $data;break;
        }        
    }
    
    
}